using System;
using System.Linq;
using Habanero.Base;
using Habanero.Base.Exceptions;

namespace FireStarterModeller.BO
{
    /// <summary>
    /// A <see cref="IBusinessObjectRule"/> that validates that a <see cref="SubClass"/>
    /// has at least one <see cref="DMProperty"/>
    /// </summary>
    public class DMClassSubClassPropertyNameNotSameAsSuperClassPropertyName : IBusinessObjectRule
    {
        private DMClass _subClass;
        private DMProperty _foundProp;


//        public DMClassSubClassPropertyNameNotSameAsSuperClassPropertyName(DMClass dmClass)
//        {
//            if (dmClass == null) throw new ArgumentNullException("dmClass");
//            _subClass = dmClass;
//           
//        }

        #region Implementation of IBusinessObjectRule

        /// <summary>
        /// Indicates whether the property value is valid against the rules
        /// </summary>
        /// <returns>
        /// Returns true if valid
        /// </returns>
        public bool IsValid()
        {
            throw new HabaneroApplicationException("The IsValid is no longer Valid you should use the IsValid(bo) method");
        }

        public bool IsValid(IBusinessObject bo)
        {
            _subClass = (DMClass) bo;
            return !HasSamePropAsSuperClass();
        }

        private bool HasSamePropAsSuperClass()
        {
            DMClass subClass = SubClass;
            if(!subClass.HasSuperClass) return false;

            DMClass superClass = this.SubClass.SuperClass;
            _foundProp = GetMatchingProperty(subClass, superClass);

            while (_foundProp==null && superClass.HasSuperClass)
            {
                superClass = superClass.SuperClass;
                _foundProp = GetMatchingProperty(subClass, superClass);
            }
           return _foundProp != null;
        }

        private static DMProperty GetMatchingProperty(DMClass subClass, DMClass superClass)
        {
            return superClass.Properties.FirstOrDefault(property => subClass.OwnsProperty(property.PropertyName));
        }


        /// <summary>
        /// Returns the rule name
        /// </summary>
        public string Name
        {
            get { return "SubClassPropertyNameNotSameAsSuperClassPropertyName"; }
        }

        /// <summary>
        /// Returns the error message for if the rule fails.
        /// </summary>
        public string Message
        {
            get { return "The SubClass '" + SubClass + "' must not have same Property Name '" + _foundProp.PropertyName + "' as it's SuperClass '" + SubClass.SuperClass + "'"; }
        }
        /// <summary>
        /// The <see cref="P:Habanero.Base.IBusinessObjectRule.ErrorLevel" /> for this BusinessObjectRule e.g. Warning, Error. 
        /// </summary>
        public ErrorLevel ErrorLevel
        {
            get { return Habanero.Base.ErrorLevel.Warning; }
        }

        public DMClass SubClass
        {
            get { return _subClass; }
        }

        #endregion
    }
}